package com.ruoyi.rulengine.evaluator;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import com.ruoyi.iotcommon.domain.DeviceDataMessage;
import com.ruoyi.rulengine.domain.RuleCondition;

@Slf4j
@Service
public class DefaultRuleConditionEvaluator implements RuleConditionEvaluator{

    private static final String GREATER_THAN = ">";
    private static final String LESS_THAN = "<";
    private static final String EQUAL = "=";
    private static final String GREATER_THAN_OR_EQUAL = ">=";
    private static final String LESS_THAN_OR_EQUAL = "<=";
    private static final String NOT_EQUAL = "!=";
    private static final String CONTAINS = "in";

    /**
     * 表达式计算后续再支持
     * @param condition
     * @param deviceData
     * @return
     */
    @Override
    public RuleCondition evaluate(RuleCondition condition, DeviceDataMessage deviceData) {
        if (condition == null || deviceData == null || deviceData.getParams() == null) {
            log.warn("输入参数不能为空");
            if (condition != null) {
                condition.setIsMatched(false);
            }
            return condition;
        }

        String propertyKey = condition.getPropertyKey();
        String operatorType = condition.getOperatorType();
        String propertyValue = condition.getPropertyValue();

        // 检查必要参数
        if (propertyKey == null || operatorType == null || propertyValue == null) {
            log.warn("条件参数不完整: propertyKey={}, operatorType={}, propertyValue={}",
                    propertyKey, operatorType, propertyValue);
            condition.setIsMatched(false);
            return condition;
        }

        // 从设备数据的 params 中获取属性值
        Object actualValue = deviceData.getParams().get(propertyKey);

        if (actualValue == null) {
            log.warn("属性不存在: {}", propertyKey);
            condition.setIsMatched(false);
            return condition;
        }

        boolean isMatched;
        try {
            // 根据比较符进行判断
            if (actualValue instanceof Number) {
                // 数字类型比较
                double actualNum = ((Number) actualValue).doubleValue();
                double conditionNum = Double.parseDouble(propertyValue);

                isMatched = switch (operatorType) {
                    case GREATER_THAN -> actualNum > conditionNum;
                    case LESS_THAN -> actualNum < conditionNum;
                    case EQUAL -> Math.abs(actualNum - conditionNum) < 0.000001; // 处理浮点数精度问题
                    case GREATER_THAN_OR_EQUAL -> actualNum >= conditionNum;
                    case LESS_THAN_OR_EQUAL -> actualNum <= conditionNum;
                    case NOT_EQUAL -> Math.abs(actualNum - conditionNum) > 0.000001;
                    default -> throw new IllegalArgumentException("未知的数字比较符: " + operatorType);
                };
            } else if (actualValue instanceof Boolean) {
                // 布尔类型比较
                if (!(EQUAL.equals(operatorType) || NOT_EQUAL.equals(operatorType))) {
                    throw new IllegalArgumentException("布尔类型只支持 EQUAL 和 NOT_EQUAL 操作符");
                }
                boolean conditionBool = Boolean.parseBoolean(propertyValue);
                boolean actualBool = (Boolean) actualValue;
                isMatched = EQUAL.equals(operatorType) == (actualBool == conditionBool);
            } else if (actualValue instanceof String actualStr) {
                // 字符串类型比较
                isMatched = switch (operatorType) {
                    case EQUAL -> actualStr.equals(propertyValue);
                    case NOT_EQUAL -> !actualStr.equals(propertyValue);
                    case CONTAINS -> actualStr.contains(propertyValue);
                    default -> throw new IllegalArgumentException("未知的字符串比较符: " + operatorType);
                };
            } else {
                // 其他类型比较
                String actualStr = String.valueOf(actualValue);
                isMatched = switch (operatorType) {
                    case EQUAL -> actualStr.equals(propertyValue);
                    case NOT_EQUAL -> !actualStr.equals(propertyValue);
                    default -> throw new IllegalArgumentException("不支持的操作符: " + operatorType + " 对于类型: " + actualValue.getClass().getSimpleName());
                };
            }
        } catch (NumberFormatException e) {
            log.warn("条件值格式错误: {}={}", propertyKey, propertyValue, e);
            condition.setIsMatched(false);
            return condition;
        } catch (IllegalArgumentException e) {
            log.warn("比较操作错误: {}", e.getMessage(), e);
            condition.setIsMatched(false);
            return condition;
        }
        condition.setIsMatched(isMatched);
        return condition;
    }

}
